Prisma のデータシーディングのベストプラクティス
自分で試したなかで最良だった方法とその理由
CSV から読み込んで大量挿入とかを upsert でやるのは厳しい
並列化が面倒だし、適当にやるとコネクションプールが枯渇する
きちんと unique 制約をかけて createMany で入れたほうがよい (PostgreSQL 限定)
createMany は挿入したいデータを配列で受け取ってくれる
並列化とかも勝手に面倒見てくれる
createMany には skipDuplicates というオプションがある
ON CONFLICT DO NOTHING をサポートするエンジンでのみ使える
多分サポートしてるのは PostgreSQL しかない
きちんと unique を指定していれば同じデータが来ても制約に引っかかるので挿入されない
しかもエラーも出ない!
upsert でやるなら適当にスロットルしてあげつつ Promise.all でぶん回すと良さそう
標準のコネクションプールは8つなので
code:throttle.ts
export const awaiter = ({ parallel }: { parallel: number }) => {
let running = 0
const addQueue = async <T>(p: () => Promise<T>): T => {
while (running > parallel) await sleep(Math.floor(Math.random() * 1000))
running++
const res = await p()
running--
return res
}
const getQueue = () => running
}
みたいなのを用意して
code:upsert.ts
const addQueue = awaiter({ parallel: 8 }) await Promise.all(lines.map(async (l) => addQueue(async () => prisma.hoge.upsert({ data: l }))))
みたいにすると良いと思う
ただこのコードだと同時実行数が parallel + 1 になっちゃう気がする…